package tech.wisefin.track.session;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import tech.wisefin.track.EvidenceProvider;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.client.RestTemplate;
import tech.wisefin.track.TrackConfiguration;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.lang.Thread.sleep;

@Slf4j
@Service
public class SessionTrackService {

    private final SessionTrackRepository trackRepo;
    private final EvidenceProvider evidenceProvider;
    private final TrackConfiguration config;

    public SessionTrackService(TrackConfiguration config, EvidenceProvider evidenceProvider, SessionTrackRepository trackRepository) {
        this.config = config;
        this.trackRepo = trackRepository;
        this.evidenceProvider = evidenceProvider;
    }

    @Async
    public void makeVideo(String session) {
        try {
            // XXX: 异步调用，并延时1秒保证数据已经保存至数据库
            // 否则立刻调用可能会导致无法获取数据
            sleep(1000);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            Map<String, String> map = new HashMap<>();
            map.put("session", session);

            new RestTemplate().exchange(
                    config.getVideoEndpoint(),
                    HttpMethod.POST,
                    new HttpEntity<>(map, headers),
                    String.class
            );
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据session合并相同的动作片段，用于后续视频生成
     *
     * @param fragment 前端提交的行为动作片段
     * @return 行为追踪数据
     */
    public SessionTrack track(String session, SessionTrackFragment fragment) {
        SessionTrack track = trackRepo.findBySession(session)
                .orElse(new SessionTrack(session));

        track.addFragment(fragment);
        SessionTrack res = trackRepo.save(track);
        // 用户行为保存后需要生成视频
        makeVideo(session);
        return res;
    }

    public Optional<SessionTrack> getSessionTrack(String session) {
        return trackRepo.findBySession(session);
    }

    public Iterable<SessionTrackView> getSessionTrack() {
        return trackRepo
                .findAll()
                .stream()
                .map(SessionTrackView::new)
                .collect(Collectors.toList());
    }


    public void attach(SessionTrack track, File video) {
        if (track.isLocked()) {
            log.warn(track.getSession() + "，SessionTrack 已被锁定");
            return;
        }

        track.setVideoFileName(video.getName());
        String evidence = evidenceProvider.provide(video);
        track.setEvidence(evidence);
        trackRepo.save(track);
    }

}
